package com.iqismart.shorturl.utils;

import com.iqismart.shorturl.exception.UserTokenInValidException;
import com.iqismart.shorturl.exception.UserTokenRequireException;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.SignatureException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 * @Description
 * @Auther sty
 * @createTime 2019/10/14 01:52
 */
public class UserTokenUtils {
    public static SecretKeySpec secretKeySpec = new SecretKeySpec("sty1sdjjdfjhjdfhdjfhdjhfdjhfdjfhjdf231233".getBytes(), SignatureAlgorithm.HS512.getJcaName());

    public UserTokenUtils() {
    }

    public static long getUID() {
        String token = getTokenFromRequest();
        if (StringUtils.isEmpty(token)) {
            throw new UserTokenRequireException();
        } else {
            return decode(token);
        }
    }

    public static long getUID(HttpServletRequest request) {
        String token = getTokenFromRequest(request);
        if (StringUtils.isEmpty(token)) {
            throw new UserTokenRequireException();
        } else {
            return decode(token);
        }
    }

    public static String getTokenFromRequest() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            return null;
        } else {
            HttpServletRequest request = requestAttributes.getRequest();
            if (request == null) {
                throw new RuntimeException("不能获取到 request ");
            } else {
                return getTokenFromRequest(request);
            }
        }
    }

    public static String getTokenFromRequest(HttpServletRequest request) {
        if (request == null) {
            throw new RuntimeException("不能获取到 request ");
        } else {
            String token = request.getHeader("access_token");
            if (StringUtils.isEmpty(token)) {
                token = request.getParameter("access_token");
            }

            if (StringUtils.isEmpty(token)) {
                final Cookie[] cookies = request.getCookies();
                if(cookies != null){
                    for (Cookie cookie : cookies) {
                        if(cookie.getName().equals("u1rl_cn_token")){
                            token = cookie.getValue();
                        }
                    }
                }

            }

            return token;
        }
    }

    /*public static void setTokenToRequest(String token) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (StringUtils.isNotEmpty(token)) {
            request.setAttribute("access_token", token);
        }

    }*/

    public static Long decode(String token) {
        if (StringUtils.isEmpty(token)) {
            return 0L;
        } else {
            try {
                Claims body = Jwts.parser().setSigningKey(secretKeySpec).parseClaimsJws(token).getBody();
                JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(body));
                return jsonObject.getLong("uid");
            } catch (SignatureException e1){
                throw new UserTokenInValidException("非法token");
            }catch (Exception e) {
                e.printStackTrace();
            }
            return 0L;
        }
    }

    public static String encode(Long uid) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("uid",uid);
        return  Jwts.builder().setPayload(jsonObject.toJSONString())
                .compressWith(CompressionCodecs.DEFLATE).signWith(secretKeySpec).compact();
    }

    public static void main(String[] args) {
        String encode = encode(1L);
        System.out.println(encode);

        System.out.println(decode("eyJhbGciOiJIUzI1NiIsInppcCI6IkRFRiJ9.eJyrVirNTFGyMqwFAA8eAuo.RxAx9fFW4YAUkRK8ZNzrbtMSJutDceAuKoTkXkHlEBA"));
    }
}